#include "StdAfx.h"
#include "Sprite.h"

Sprite::Sprite(void)
{
}

Sprite::~Sprite(void)
{
}
int Sprite::Init(char* texture_path, float duration, float width, float height, int num_sprites_X, int num_sprites_Y, int num_sprites)
{
	totalTime = 0;
	this->duration = duration;
	this->numSprites = num_sprites;
	this->numSpritesX = num_sprites_X;
	this->numSpritesY = num_sprites_Y;
	//
	int img_width, img_height, bpp;
	char* img_buffer = LoadTGA(texture_path, &img_width, &img_height, &bpp);
	glGenTextures(1, &texture_id);
	glBindTexture(GL_TEXTURE_2D, texture_id);
	if (bpp == 24)
	{
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img_width, img_height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_buffer);
	}
	else if (bpp == 32)
	{
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img_width, img_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_buffer);
	}
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glBindTexture(GL_TEXTURE_2D, 0);
	delete[] img_buffer;

	//triangle data (heap)
	Vertex verticesData[6];

	verticesData[0].pos.x = -width / 2;  verticesData[0].pos.y = height / 2;  verticesData[0].pos.z = 0.0f;
	verticesData[1].pos.x = -width / 2;  verticesData[1].pos.y = -height / 2;  verticesData[1].pos.z = 0.0f;
	verticesData[2].pos.x = width / 2;  verticesData[2].pos.y = -height / 2;  verticesData[2].pos.z = 0.0f;

	verticesData[3].pos.x = -width / 2;  verticesData[3].pos.y = height / 2;  verticesData[3].pos.z = 0.0f;
	verticesData[4].pos.x = width / 2;  verticesData[4].pos.y = height / 2;  verticesData[4].pos.z = 0.0f;
	verticesData[5].pos.x = width / 2;  verticesData[5].pos.y = -height / 2;  verticesData[5].pos.z = 0.0f;
	// test uv
	float dx = float(1) / num_sprites_X;
	float dy = float(1) / num_sprites_Y;
	int i = 0; int j = 0;
	verticesData[0].uv.x = i * dx;  verticesData[0].uv.y = img_height - j * dy;
	verticesData[1].uv.x = i * dx;  verticesData[1].uv.y = img_height - j * dy - dy;
	verticesData[2].uv.x = i * dx + dx;	  verticesData[2].uv.y = img_height - j * dy - dy;

	verticesData[3].uv.x = i * dx;	verticesData[3].uv.y = img_height - j * dy;
	verticesData[4].uv.x = i * dx + dx;		verticesData[4].uv.y = img_height - j * dy;
	verticesData[5].uv.x = i * dx + dx;		verticesData[5].uv.y = img_height - j * dy - dy;


	//buffer object
	glGenBuffers(1, &vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(verticesData), verticesData, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	//creation of shaders and program 
	myShaders.Init("../Resources/Shaders/SpriteShaderVS.vsh", "../Resources/Shaders/SpriteShaderFS.fsh");
	aTexCoord = glGetAttribLocation(myShaders.program, "a_TexCoord");
	uTexture = glGetUniformLocation(myShaders.program, "u_texture");

	//
	uDx = glGetUniformLocation(myShaders.program, "u_dx");
	uDy = glGetUniformLocation(myShaders.program, "u_dy");
	return 0;
}

void Sprite::Draw()
{

	glUseProgram(myShaders.program);

	glBindBuffer(GL_ARRAY_BUFFER, vbo);


	if (myShaders.positionAttribute != -1)
	{
		glEnableVertexAttribArray(myShaders.positionAttribute);
		glVertexAttribPointer(myShaders.positionAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
	}
	if (aTexCoord != -1)
	{
		glEnableVertexAttribArray(aTexCoord);
		glVertexAttribPointer(aTexCoord, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (char*)0 + sizeof(Vector3));
	}

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, texture_id);
	glUniform1i(uTexture, 0);

	//glUniform1f(uTotalTimeLocation, 0);

	glDrawArrays(GL_TRIANGLES, 0, 6);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindTexture(GL_TEXTURE_2D, 0);
}

void Sprite::Update(float deltaTime)
{
	totalTime += deltaTime;
	// Duration for each frame
	float dFrameTime = duration / float(numSprites);

	// Find index for current frame
	int i = int(totalTime / dFrameTime) % numSprites;
	int ix = i % numSpritesX;
	int iy = i / numSpritesX;

	// Set texture Coordinates displacement
	float dx = float(ix) / float(numSpritesX);
	float dy = float(iy) / float(numSpritesY);

	// Pass displacement to GPU
	glUniform1f(uDx, dx);
	glUniform1f(uDy, dy);    
}